package com.uft.service;

import java.util.Calendar;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;

import com.uft.model.dao.PreferencesDAO;
import com.uft.model.dao.ProfileDAO;
import com.uft.model.dao.ServerDAO;
import com.uft.model.entity.Preferences;
import com.uft.model.entity.Profile;
import com.uft.model.entity.ProfilePreferences;
import com.uft.model.entity.Server;
import com.uft.was.app.WasAppManager;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;


@Service
public class DeployService {
	
	@Autowired
	ProfileDAO profileDAO;
	@Autowired
	ServerDAO serverDAO;
	@Autowired
	PreferencesDAO preferencesDAO;
	private  static Logger  logger = Logger.getLogger(DeployService.class);
 	Hashtable<String, WasAppManager> wasApplicationManagerTable= new Hashtable<String, WasAppManager>();
 	
 	public boolean addDeploymentTask(String id, HashMap<String, String> options){
 		WasAppManager wasAppMgr;
 		logger.debug("Size of WAS App Manager "+wasApplicationManagerTable.size());
 		if(!wasApplicationManagerTable.containsKey(id)){
 			wasAppMgr=addWasAppManager(id);
 			wasApplicationManagerTable.put(id, wasAppMgr);
 			logger.info("creating a new server deployment object: "+id);
 		}
 		else{
 			if(!wasApplicationManagerTable.get(id).isRunning()){
 				wasApplicationManagerTable.remove(id);
 				wasAppMgr=addWasAppManager(id);
 	 			wasApplicationManagerTable.put(id, wasAppMgr);
 	 			logger.info("Refreshing server deployment object: "+id);
 			}
 		}
 		
 		return wasApplicationManagerTable.get(id).addDeploymentTask(options);
 	}
 	public boolean stopRunningTask(String id){
 		if(wasApplicationManagerTable.containsKey(id)){
 			wasApplicationManagerTable.get(id).getWasDeployCommand();
 			return true;
 		}
 		return false;
 	}
 	public WasAppManager addWasAppManager(String id){
 		WasAppManager wasAppMgr=new WasAppManager();
 		wasAppMgr.setId(id);
 		Server server= serverDAO.getServerById(Integer.parseInt(id));
 		Profile profile= profileDAO.getProfileByServerId(Integer.parseInt(id));
 		if(server != null && profile != null){
 			logger.debug("Server and Profile is valid...continueing.. "+id);
 			ProfilePreferences profilePref=profile.getProfilePref();
 			logger.debug("profilePref "+ profilePref);
 			wasAppMgr.setServerName(server.getServerName());
 			wasAppMgr.setHostname(profile.getHostname());
 			wasAppMgr.setDmgrUsername(profile.getUsername());
 			wasAppMgr.setDmgrPassword(profile.getPassword());
 			wasAppMgr.setSecurity(Boolean.parseBoolean(profile.getSecurity()));
 			if(profilePref.getSshEnabled() != null && profilePref.getSshEnabled().equalsIgnoreCase("true")){
 				logger.debug("Remote Execution is enabled..."+id);
 				wasAppMgr.setRemoteExecute(true);
 				wasAppMgr.setPort("22");
 				wasAppMgr.getWasDeployCommand().setSshUsername((profilePref.getSshUsername()));
 				wasAppMgr.getWasDeployCommand().setSshPassword(profilePref.getSshPassword());
 			}
 			if(profilePref.getScriptPath() != null && !profilePref.getScriptPath().equalsIgnoreCase("")){
 				wasAppMgr.setScriptPath(profilePref.getScriptPath());
 			}else{
 				Preferences pref=preferencesDAO.getPreferencesByName("scriptPath");
 				if(pref != null ){
 					wasAppMgr.setScriptPath(pref.getPrefValue());
 				}
 			}
 			if(profilePref.getDeployScript() != null && !profilePref.getDeployScript().equalsIgnoreCase("")){
 				wasAppMgr.getWasDeployCommand().setDeployScript(profilePref.getDeployScript());
 			}
 			if(profilePref.getDeployScriptSudo() != null && !profilePref.getDeployScriptSudo().equalsIgnoreCase("")){
 				wasAppMgr.getWasDeployCommand().setSudoCommand(profilePref.getDeployScriptSudo());
 			}
 			Preferences serverPrefixPref=preferencesDAO.getPreferencesByCategoryName("APPLICATION", "SERVER_PREFIX");
			if(serverPrefixPref != null ){
				wasAppMgr.setServerPrefix(serverPrefixPref.getPrefValue());
			}
			Preferences serverSuffixPref=preferencesDAO.getPreferencesByCategoryName("APPLICATION", "SERVER_SUFFIX");
			if(serverSuffixPref != null ){
				wasAppMgr.setServerSuffix(serverSuffixPref.getPrefValue());
			}
 		}
 		return wasAppMgr;
 
 	}
 	public HashMap<String,String> getDeploymentStatusAll(String id){
 		HashMap<String,String> result=new HashMap<String,String>();
 		if(wasApplicationManagerTable.containsKey(id)){
 			if(wasApplicationManagerTable.get(id).isRunning()){
 				result.put("status", "RUNNING");
 			}else{
 				result.put("status", "STOPPED");
 			}
 			result.put("output", wasApplicationManagerTable.get(id).getOutputBuffer().toString());
 			result.put("error", wasApplicationManagerTable.get(id).getErrorBuffer().toString());
 			result.put("code", String.valueOf(wasApplicationManagerTable.get(id).getErrorCode()));
 			
 			if(wasApplicationManagerTable.get(id).getStartTime() != null){
 				result.put("startTime", wasApplicationManagerTable.get(id).getStartTime().getTime().toString());
 			}else{
 				result.put("startTime", "");
 			}
 			
 			if(wasApplicationManagerTable.get(id).getEndTime() != null){
 				result.put("endTime", wasApplicationManagerTable.get(id).getEndTime().getTime().toString());
 			}else{
 				result.put("endTime", "");
 			}
 			
 			
 		}else{
 			result.put("status", "N/A");
 		}
 		logger.debug("ID: "+id+" output: "+result);
 		return result;
 	}
 	public boolean getDeploymentStatus(String id){
 		if(wasApplicationManagerTable.containsKey(id)){
 			return wasApplicationManagerTable.get(id).isRunning();
 		}
 		return false;
 	}
 	public String getDeploymentOuput(String id){
 		if(wasApplicationManagerTable.containsKey(id)){
 			return wasApplicationManagerTable.get(id).getOutputBuffer().toString();
 		}else{
 			return "";
 		}
 	}
 	public String getDeployError(String id){
 		if(wasApplicationManagerTable.containsKey(id)){
 			return wasApplicationManagerTable.get(id).getErrorBuffer().toString();
 		}else {
 			return "";
 		}
 	}
 	
 	public int getDeployErroCode(String id){
 		if(wasApplicationManagerTable.containsKey(id)){
 			return wasApplicationManagerTable.get(id).getErrorCode();
 		}else{
 			return -1;
 		}
 	}
 	public void clearDeployment(String id){
 		if(wasApplicationManagerTable.containsKey(id)){
 			logger.debug("Clearing Stopped Deployment...."+id);
 			wasApplicationManagerTable.get(id).clearError();
 			wasApplicationManagerTable.get(id).clearOutput();
 			wasApplicationManagerTable.get(id).clearStartTime();
 			wasApplicationManagerTable.get(id).clearEndTime();
 			wasApplicationManagerTable.get(id).clearCode();
 		}
 	}
 	
 	public List<String> getDeployFiles(String id){
 		WasAppManager wasAppMgr;
 		if(wasApplicationManagerTable.containsKey(id)){
 			wasAppMgr=wasApplicationManagerTable.get(id);
 		}else{
 			wasAppMgr=addWasAppManager(id);
 		}
 		return wasAppMgr.getWasDeployCommand().getDeployFiles();
 		
 	}
 	@Scheduled(fixedDelayString="${deployService.clearDeploymentQueueSchedule.fixedDelay:60000}")
 	public void clearDeploymentQueueSchedule(){
 		logger.trace("Deployment Timer..."+Calendar.getInstance().getTime().toString());
 		 Enumeration keys = wasApplicationManagerTable.keys();
 		while(keys.hasMoreElements()){
 			String id=(String) keys.nextElement();
 			if(!wasApplicationManagerTable.get(id).isRunning() && wasApplicationManagerTable.get(id).getEndTime() != null){
 				logger.trace("clearDeploymentQueueSchedule is clearing id..."+id);
 				clearDeployment(id);
 			}
 		}
 			
 		 
 	}
}
